package com.leeoohoo.security;

import cn.hutool.json.JSONUtil;
import com.leeoohoo.config.RedisUtils;
import com.leeoohoo.dto.AuthRole;
import com.leeoohoo.dto.MyUserDetails;
import com.leeoohoo.service.UserService;
import com.leeoohoo.user.MyUser;
import com.leeoohoo.user.MyUserService;
import com.leeoohoo.user.RuleEnum;
import com.leeoohoo.utils.HooBeanUtils;
import com.oohoo.spacestationspringbootstarter.dto.query.EQ;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Objects;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SecurityUserService implements UserService {


    private final MyUserService userService;

    @Override
    public void saveCacheUser(MyUserDetails user, String token, Long expired) {
        String userJson = JSONUtil.toJsonStr(user);
        RedisUtils.set(token, userJson);
        if (expired > 0) {
            RedisUtils.set(token, userJson, Duration.ofSeconds(expired));
        }
    }


    @Override
    public Mono<MyUserDetails> findByToken(String token, Long expired) {
        Mono<String> userJsonMono = RedisUtils.get(token);
        return userJsonMono.map(it -> {
            MyUserDetails myUserDetails = JSONUtil.toBean(it, MyUserDetails.class);
            if (expired > 0) {
                RedisUtils.set(token, it, Duration.ofSeconds(expired));
            }
            return myUserDetails;
        });
    }

    @Override
    public Mono<UserDetails> findByUsername(String username) {
        return this.valid(username);
    }

    private Mono<UserDetails> valid(String username) {
        MyUser one = userService.getButler().findOne(
                EQ.find(MyUser.class)
                        .select(MyUser.class)
                        .where()
                        .eq(MyUser::getUsername, username),
                MyUser.class
        );
        if (Objects.isNull(one)) {
            throw new UsernameNotFoundException("账户不存在");
        }
        MyUserDetails myUserDetails = HooBeanUtils.copyProperties(MyUserDetails.class, one);
        ArrayList<AuthRole> objects = new ArrayList<>();
        if (one.getAdministratorFlag() > 0) {
            objects.add(new AuthRole().setName(RuleEnum.ADMIN.getRule()));
        }
        objects.add(new AuthRole().setName(RuleEnum.USER.getRule()));
        myUserDetails.setRoleList(objects);
        return Mono.just(myUserDetails);
    }


}
